import React, {
  useState,
  useMemo,
  useRef,
  createContext,
  useEffect,
  createElement,
} from "react";
import {
  Tree,
  Input,
  Popconfirm,
  Tooltip,
  Divider,
  Modal,
  message,
  Button,
  Form,
} from "antd";
import {
  MinusSquareOutlined,
  FormOutlined,
  PlusSquareOutlined,
  ArrowDownOutlined,
  ArrowRightOutlined,
  SmileFilled,
  PlusOutlined,
  ArrowUpOutlined,
} from "@ant-design/icons";
import * as Icons from "@ant-design/icons";
import { useModel } from "umi";
import { ProForm } from "@ant-design/pro-components";
import { ProFormText } from "@ant-design/pro-components";
import IconFont from "../IconFont";
let { Search } = Input;

const getParentKey = (path, tree) => {
  let parentKey;
  for (let i = 0; i < tree.length; i++) {
    const node = tree[i];
    if (node.routes) {
      if (
        node.routes.some((item) => {
          return item.path === path;
        })
      ) {
        parentKey = node.path;
      } else if (getParentKey(path, node.routes)) {
        parentKey = getParentKey(path, node.routes);
      }
    }
  }
  return parentKey;
};

function updateNodeByPath(data, pathToUpdate, updatedNodeInfo) {
  return data.map((item) => {
    if (item.path === pathToUpdate) {
      return { ...item, ...updatedNodeInfo };
    } else if (item.routes) {
      return {
        ...item,
        routes: updateNodeByPath(item.routes, pathToUpdate, updatedNodeInfo),
      };
    }
    return item;
  });
}

function deleteNodeByPath(data, pathToDelete) {
  return data.filter((node) => {
    if (node.path === pathToDelete) {
      return false;
    } else if (node.routes) {
      node.routes = deleteNodeByPath(node.routes, pathToDelete);
      return true;
    } else {
      return true;
    }
  });
}

function addNodeToRoutesByPath(data, pathToAdd, newNode) {
  return data.map((node) => {
    if (node.path === pathToAdd) {
      return {
        ...node,
        routes: [...(node?.routes ?? []), newNode],
      };
    } else if (node.routes) {
      return {
        ...node,
        routes: addNodeToRoutesByPath(node.routes, pathToAdd, newNode),
      };
    } else {
      return node;
    }
  });
}

function TreeRender({
  dataSource,
  onselected,
  params,
  noaction,
  maxWidth,
  style,
  setDom,
}) {
  const [form] = Form.useForm();

  const {
    initialState: { routerData },
    setInitialState,
  } = useModel("@@initialState");

  const [search, setsearch] = useState("");
  const [modal, setModal] = useState({
    open: false,
  });
  const [expandall, setexpandall] = useState(false);
  const [expandedKeys, onExpand] = useState(),
    [selectedKeys, cselectedKeys] = useState([]);

  const [autoExpandParent, setAutoExpandParent] = useState(true);

  const allkeys = useMemo(() => {
    let res = [];
    const fn = (source) => {
      source.map((el) => {
        res.push(el);
        el.routes && el.routes.length > 0 ? fn(el.routes) : ""; // 子级递归
      });
    };
    fn(dataSource);
    return res.filter((it) => it.routes).map((it) => it.path);
  }, [dataSource]);

  const onChange = (e) => {
    const { value } = e.target;
    const dataLists = getAllList();
    const newExpandedKeys = dataLists
      .map((item) => {
        if (item.name.indexOf(value) > -1) {
          return getParentKey(item.path, dataSource);
        }
        return null;
      })
      .filter((item, i, self) => item && self.indexOf(item) === i);
    setsearch(value);
    if (newExpandedKeys.length > 0) {
      setexpandall(true);
      setAutoExpandParent(true);
    } else {
      setexpandall(false);
      setAutoExpandParent(false);
    }
    onExpand(newExpandedKeys);
  };

  const loop = (data) =>
    data.map((item) => {
      const index = item.name.indexOf(search);
      const beforeStr = item.name.substr(0, index);
      const afterStr = item.name.substr(index + search.length);
      let name =
        index > -1 ? (
          <span
            style={{
              display: "inline-block",
              maxWidth: maxWidth ?? 88,
              overflow: "hidden",
              textOverflow: "ellipsis",
              whiteSpace: "nowrap",
              marginRight: 6,
            }}
          >
            {beforeStr}
            <span style={{ color: "#f50" }}>{search}</span>
            {afterStr}
          </span>
        ) : (
          <span
            style={{
              display: "inline-block",
              maxWidth: maxWidth ?? 88,
              overflow: "hidden",
              textOverflow: "ellipsis",
              whiteSpace: "nowrap",
              marginRight: 6,
            }}
          >
            {item.name}
          </span>
        );

      const actiontitle = (
        <div
          id={item.path}
          style={{
            display: "flex",
            alignItems: "center",
            justifyContent: "space-between",
            gap: 12,
          }}
        >
          {typeof item?.icon === "string" ? (
            item.icon.includes("http") ? (
              <img src={item.icon} alt="" style={{ width: 16 }} />
            ) : (
              <IconFont type={item?.icon}></IconFont>
            )
          ) : (
            item.icon
          )}
          <Tooltip title={item?.name}>{name}</Tooltip>
          <div>
            {item.path && item.path != "00000000" && (
              <Tooltip
                title="编辑"
                onClick={(e) => {
                  e.stopPropagation();
                  if (true) {
                    setModal({
                      open: true,
                      closable: true,
                      title: "修改节点",
                      okText: "修改",
                      cancelText: "取消",
                      placeholder: item.name,
                      path: item.path,
                    });
                    setTimeout(() => {
                      form.setFieldsValue(item);
                    }, 400);
                  }
                }}
              >
                <FormOutlined style={{ color: "#1890ff" }} />
              </Tooltip>
            )}

            {item.path && item.path != "00000000" && (
              <Divider type="vertical" style={{ margin: "0 6px" }}></Divider>
            )}

            <Tooltip title="新增">
              <PlusSquareOutlined
                disabled={false}
                onClick={(e) => {
                  e.stopPropagation();
                  if (true) {
                    setModal({
                      open: true,
                      closable: true,
                      title: "新增 " + item.name + " 的子页面",
                      okText: "新增",
                      cancelText: "取消",
                      path: item.path,
                    });
                    form.resetFields();
                  }
                }}
                style={{
                  color: `${true ? "green" : ""}`,
                }}
              />
            </Tooltip>

            {(!item.routes || item.routes.length == 0) && (
              <Divider type="vertical" style={{ margin: "0 6px" }}></Divider>
            )}
            {(!item.routes || item.routes.length == 0) && item.path != "0" && (
              <Popconfirm
                title="是否删除该节点？"
                okText="删除"
                cancelText="取消"
                onConfirm={(e) => {
                  e.stopPropagation();
                  const deletedData = deleteNodeByPath(routerData, item.path);
                  changeRouterData(deletedData);
                }}
                placement="bottom"
                getPopupContainer={() =>
                  document.getElementById("popupContainer")
                }
              >
                <MinusSquareOutlined style={{ color: "red" }} />
              </Popconfirm>
            )}
          </div>
        </div>
      );

      if (item.routes) {
        return {
          name: noaction ? name : actiontitle,
          path: item.path,
          routes: loop(item.routes),
        };
      }
      return {
        name: noaction ? name : actiontitle,
        path: item.path,
      };
    });

  useEffect(() => {
    setexpandall(true);
    onExpand(allkeys);
  }, [allkeys]);

  function getAllList() {
    const dataLists = [];
    const generateLists = (data) => {
      for (let i = 0; i < data.length; i++) {
        const node = data[i];
        const path = node.path;
        dataLists.push({ path, name: node.name, level: node.level });
        if (node.routes) {
          generateLists(node.routes, node.path);
        }
      }
    };
    generateLists(dataSource);
    return dataLists;
  }

  useEffect(() => {
    setDom(
      <Tooltip title="添加新页面">
        <Button
          style={{
            flexShrink: 0,
          }}
          icon={<PlusOutlined />}
          onClick={() => {
            setModal({
              open: true,
              closable: true,
              title: "添加新页面",
              okText: "添加",
              cancelText: "取消",
            });
          }}
        ></Button>
      </Tooltip>
    );
  }, []);

  return (
    <div style={{ ...style }} className="treenode" id="popupContainer">
      <Modal
        {...modal}
        onCancel={() => {
          setModal((s) => ({
            ...s,
            open: false,
          }));
        }}
        destroyOnClose={true}
        footer={false}
      >
        <ProForm
          form={form}
          style={{ marginTop: 24 }}
          onFinish={(values) => {
            if (modal.okText == "修改") {
              return new Promise((resolve, reject) => {
                const updateData = updateNodeByPath(
                  routerData,
                  modal?.path,
                  values
                );
                changeRouterData(updateData);
                setModal({
                  open: false,
                });
                resolve();
              });
            } else if (modal.okText == "添加") {
              const newObj = {
                ...values,
                path: `/${values?.path}`,
                component: `./${path}`,
              };
              changeRouterData([...routerData, newObj]);
              setModal({
                open: false,
              });
            } else {
              return new Promise((resolve, reject) => {
                const updatedData = addNodeToRoutesByPath(
                  routerData,
                  modal?.path,
                  {
                    ...values,
                  }
                );
                console.log("====================================");
                console.log(updatedData);
                console.log("====================================");
                changeRouterData(updatedData);
                setModal({
                  open: false,
                });
              });
            }
          }}
        >
          <ProFormText
            label="页面名称"
            required
            name="name"
            formItemProps={{
              rules: [
                {
                  required: true,
                  message: "页面名称必填",
                },
              ],
            }}
          ></ProFormText>
          <ProFormText
            label="页面路径"
            required
            name="path"
            formItemProps={{
              rules: [
                {
                  required: true,
                  message: "页面路径必填",
                },
              ],
            }}
          ></ProFormText>
          <ProFormText
            label="icon"
            tooltip={
              <a
                style={{ color: "white" }}
                target="_blank"
                href="https://www.iconfont.cn/manage/index?manage_type=myprojects&projectId=3865952"
              >
                图标库
              </a>
            }
            name="icon"
          ></ProFormText>
        </ProForm>
      </Modal>

      <div className="spread" style={{ gap: 6, marginBottom: 12 }}>
        <Search value={search} placeholder="搜索" onChange={onChange} />
        <Tooltip
          title={expandall ? "收起" : "展开"}
          onClick={(e) => {
            e.stopPropagation();
            setexpandall(!expandall);
            onExpand(expandall ? [] : allkeys);
            setAutoExpandParent(!expandall);
          }}
        >
          <Button
            style={{
              flexShrink: 0,
            }}
            icon={
              !expandall ? (
                <ArrowDownOutlined style={{ color: "rgba(0,0,0,0.85)" }} />
              ) : (
                <ArrowUpOutlined style={{ color: "rgba(0,0,0,0.85)" }} />
              )
            }
          ></Button>
        </Tooltip>
      </div>

      <div className="element">
        <Tree
          onSelect={(selectedKeys, e) => {
            cselectedKeys(selectedKeys);
            onselected?.(selectedKeys);
          }}
          fieldNames={{
            title: "name",
            key: "path",
            children: "routes",
          }}
          autoExpandParent={autoExpandParent}
          defaultExpandAll={true}
          expandedKeys={expandedKeys}
          selectedKeys={selectedKeys}
          onExpand={(expandedKeys, { expanded: bool, node }) => {
            onExpand(expandedKeys);
            setAutoExpandParent(false);
            if (!bool && node.path == "00000000") {
              setexpandall(false);
            } else {
              setexpandall(true);
            }
          }}
          treeData={loop(routerData ?? [])}
        ></Tree>
      </div>
    </div>
  );

  function changeRouterData(routerData) {
    setInitialState((s) => ({
      ...s,
      routerData,
    }));
  }
}

export default TreeRender;
